/*******************************************************************************
 * Copyright (c) 2008 The Eclipse Foundation and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Eclipse Foundation - initial API and implementation
 *******************************************************************************/
package org.schemeway.plugins.schemescript.views;

import java.util.*;

import org.eclipse.core.internal.resources.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.ui.packageview.ClassPathContainer;
import org.eclipse.jdt.internal.ui.packageview.LibraryContainer;
import org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider;
import org.eclipse.jdt.internal.ui.packageview.PackageFragmentRootContainer;

public class SchemePackageExplorerContentProvider extends PackageExplorerContentProvider {


	
	public SchemePackageExplorerContentProvider(boolean provideMembers) {
		super(provideMembers);
	}

	private Object[] getContainerPackageFragmentRoots(PackageFragmentRootContainer container) {
		//get rid of library Jar Files
		if (container instanceof ClassPathContainer)
			return NO_CHILDREN;
		return container.getChildren();
	}
	
	protected Object[] getPackageFragmentRoots(IJavaProject project) throws JavaModelException {
		if (!project.getProject().isOpen())
			return NO_CHILDREN;
			
		List result= new ArrayList();

		boolean addJARContainer= false;
		
		IPackageFragmentRoot[] roots= project.getAllPackageFragmentRoots();
		for (int i= 0; i < roots.length; i++) {
			IPackageFragmentRoot root= roots[i];
			IClasspathEntry classpathEntry= root.getRawClasspathEntry();
			int entryKind= classpathEntry.getEntryKind();
			if (entryKind == IClasspathEntry.CPE_CONTAINER) {
				// all ClassPathContainers are added later 
			} else if ( (entryKind == IClasspathEntry.CPE_LIBRARY || entryKind == IClasspathEntry.CPE_VARIABLE)) {
				addJARContainer= true;
			} else {
				if (isProjectPackageFragmentRoot(root)) {
					// filter out package fragments that correspond to projects and
					// replace them with the package fragments directly
					Object[] fragments= getPackageFragmentRootContent(root);
					for (int j= 0; j < fragments.length; j++) {
						result.add(fragments[j]);
					}
				} else {
					
					 if (root.getElementName().equals("src")) {
						IJavaElement[] children = root.getChildren();
						if (children != null) {
							for (int index=0; index < children.length; index ++)
								result.add(children[index]);
						}
					}
					else
					
						result.add(root);
				}
			}
		}
		
		if (addJARContainer) {
			result.add(new LibraryContainer(project));
		}
		
		// separate loop to make sure all containers are on the classpath
		IClasspathEntry[] rawClasspath= project.getRawClasspath();
		for (int i= 0; i < rawClasspath.length; i++) {
			IClasspathEntry classpathEntry= rawClasspath[i];
			if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				// don't show JRE
				//result.add(new ClassPathContainer(project, classpathEntry));
			}	
		}
		// get rid of .classpath and .project files
		/*Object[] resources= ((IJavaProject) project).getNonJavaResources();
		for (int i= 0; i < resources.length; i++) {
			result.add(resources[i]);
		}*/
		return result.toArray();
	}
	public Object[] getChildren(Object parentElement) {
		try {
			if (parentElement instanceof IJavaModel)
				return concatenate(getJavaProjects((IJavaModel)parentElement), getNonJavaProjects((IJavaModel)parentElement));

			if (parentElement instanceof PackageFragmentRootContainer)
				return getContainerPackageFragmentRoots((PackageFragmentRootContainer)parentElement);

			if (parentElement instanceof IProject) {
				IProject project= (IProject) parentElement;
				if (project.isAccessible()){
					
					/* To Remove .project from non-java projects. Pain because scheme uses
					scheme uses an empty project */
					Object[] members = project.members();
					Vector<Object> result = new Vector<Object>();
					for (int i=0; i<members.length; i++) {
						if(members[i] instanceof IResource){
							IResource res = (IResource)members[i];
							if(!res.getName().equals(".project"))
								result.add(res);
						}
					}
					if(!result.isEmpty())
						return result.toArray();
				}
				return NO_CHILDREN;
			}

			return super.getChildren(parentElement);
		} catch (CoreException e) {
			return NO_CHILDREN;
		}
	}
	private Object[] getNonJavaProjects(IJavaModel model) throws JavaModelException {
		return model.getNonJavaResources();
	}
	
}

